import hashlib
import os
import os.path
import jinja2
from flask import Blueprint, request, render_template, redirect, url_for, jsonify, session, g
from flask_restful import Api, Resource, reqparse, inputs, fields, marshal, marshal_with
from sqlalchemy import or_
from werkzeug.security import generate_password_hash, check_password_hash
from datamp.user.models import *
import random
import uuid

# 加载数据库
from ext import *
from werkzeug.utils import secure_filename
from werkzeug.datastructures import FileStorage

# 加载flask-jwt-extended
from flask_jwt_extended import (create_access_token, create_refresh_token, jwt_required, get_jwt_identity, get_jwt)

# 加载配置文件
from settings import Config

import traceback
import logging
import logging.handlers

user_bp1 = Blueprint('user', __name__, url_prefix='/user', template_folder='templates')
required_login_list = ['/user/center', '/user/change']

api = Api(user_bp1)

login_parser = reqparse.RequestParser()
login_parser.add_argument('password', type=str, help='密码不对', location=['form', 'args', 'json'])
login_parser.add_argument('role_number', type=str, help='卡号不对', location=['form', 'args', 'json'])

register_parser = reqparse.RequestParser()
register_parser.add_argument('username', type=str, help='名字不对', required=False, location=['form', 'args', 'json'])
register_parser.add_argument('user_name', type=str, help='名字不对', required=False, location=['form', 'args', 'json'])
register_parser.add_argument('real_name', type=str, help='名字不对', required=False, location=['form', 'args', 'json'])
register_parser.add_argument('password', type=str, help='密码不对', required=False, location=['form', 'args', 'json'])
register_parser.add_argument('re_password', type=str, help='密码不对', required=False, location=['form', 'args', 'json'])
register_parser.add_argument('mobile_phone', type=inputs.regex(r'^1[356789]\d{9}$'), location=['form', 'args', 'json'],
                             help='手机号码格式错误')
register_parser.add_argument('email', type=str, help='邮箱不对', required=False, location=['form', 'args', 'json'])
register_parser.add_argument('role_number', type=str, help='证件号不对', required=False, location=['form', 'args', 'json'])
register_parser.add_argument('user_right_id', type=str, help='用户角色不对', required=False,
                             location=['form', 'args', 'json'])




# 钩子函数
@user_bp1.before_app_first_request
def first_request():
    print('before_app_first_request')




# 钩子函数
@user_bp1.before_app_request
def before_request1():
    print('before_app_request', request.path)

    if request.path in required_login_list:
        id = session.get('uid')
        if not id:
            return render_template('login.html')
        else:
            user = RegisteredEducationalUserInfo.query.get(id)
            # g对象，本次请求的对象
            g.user = user
            # return render_template('login.html')


# 首页
@user_bp1.route('/')
def index():
    # cookie获取
    # uid = request.cookies.get('uid',None)
    # session获取
    # uid = session['uid']
    uid = session.get('uid')
    if uid:
        user = RegisteredEducationalUserInfo.query.get(uid)
        return render_template('index.html', user=user)
    else:
        return render_template('index.html')


# 用户注册
class UserRegister(Resource):
    def post(self):
        args = register_parser.parse_args()
        user_name = args.get('user_name')
        # 与模型结合
        user = RegisteredUser()
        user.user_name = user_name
        # user.user_right_id = user_right_id
        # 添加
        db.session.add(user)
        # 提交
        db.session.commit()
        # return redirect(url_for('index'))
        return jsonify({'code': 0, 'msg': '用户注册成功'})
    def put(self):
        args = register_parser.parse_args()
        user_name = args.get('user_name')
        real_name = args.get('real_name')
        user = RegisteredUser.query.filter(
            RegisteredUser.user_name == user_name).first()
        # 与模型结合
        # user = RegisteredUser()
        # user.user_name = user_name
        user.real_name = real_name
        # user.user_right_id = user_right_id
        # 添加
        db.session.add(user)
        # 提交
        db.session.commit()
        # return redirect(url_for('index'))
        return jsonify({'code': 0, 'msg': '用户注册成功'})
api.add_resource(UserRegister, '/UserRegister')




# # 用户注册
# class UserRegister(Resource):
#     def post(self):
#         args = register_parser.parse_args()
#         username = args.get('username')
#         password = args.get('password')
#         re_password = args.get('re_password')
#         mobile_phone = args.get('mobile_phone')
#         email = args.get('email')
#         role_number = args.get('role_number')
#         # user_right_id = args.get('user_right_id')
#         if password == re_password:
#             # 与模型结合
#             user = RegisteredEducationalUserInfo()
#             user.username = username
#             user.password = generate_password_hash(password)
#             # user.password = hashlib.sha256(password.encode('utf-8')).hexdigest()
#             print(password)
#             user.mobile_phone = mobile_phone
#             user.email = email
#             user.role_number = role_number
#             # user.user_right_id = user_right_id
#             # 添加
#             db.session.add(user)
#             # 提交
#             db.session.commit()
#             # return redirect(url_for('index'))
#             return jsonify({'code': 0, 'msg': '用户注册成功',
#                             'data': {
#                                 'username': username,
#                                 'register_date_time': user.registration_date_time
#                             }
#                             })
#         else:
#             return jsonify({'code': 1, 'msg': '用户注册失败'})
#
# api.add_resource(UserRegister, '/UserRegister')


# 用户登录
class UserLogin(Resource):

    def post(self):
        args = login_parser.parse_args()
        role_number = args.get("role_number")
        print(role_number)
        password = args.get("password")
        print(password)
        # 判断用户
        users = RegisteredEducationalUserInfo.query.filter(RegisteredEducationalUserInfo.role_number == role_number).all()
        print(users)
        for user in users:
            flag = check_password_hash(user.password, password)
            if flag:
                session['uid'] = user.id
                print('session', session)
                token = str(uuid.uuid4()).replace('-', '') + str(random.randint(100, 999))
                # token = str(uuid.uuid4()).replace('-', '') + str(random.randint(100, 999))
                print('token:', token)
                # 存储用户的登录信息
                cache.set(token, role_number)
                access_token = create_access_token(identity=user.username)
                # access_token = create_access_token(identity={'id': user.id, 'username': user.username})
                refresh_token = create_refresh_token(identity=user.username)

                return jsonify({'code': 0, 'msg': '登录成功',
                                'token': token,
                                'session': session,
                                'data': {
                                    'uid': session['uid'],
                                    'username': user.username,
                                    'user_right_id': user.user_right_id,
                                    'email': user.email,
                                    'register_date_time': user.date_time,
                                    'mobile_phone': user.mobile_phone,
                                    'role_number': user.role_number,
                                    'profile_photo': user.profile_photo
                                },
                                'access_token': access_token,
                                'refresh_token': refresh_token
                                })
                # return {'status': 200, 'msg': '用户登录成功'}
        else:
            return jsonify({'code': 1, 'msg': '该用户不存在！'})


api.add_resource(UserLogin, '/UserLogin')


# 用户退出
@user_bp1.route('logout')
def logout():
    # 1 cookie
    # response = redirect(url_for('user.index'))
    # response.delete_cookie('uid')
    # return response
    # 2 session
    # del session['uid']
    session.clear()
    return redirect(url_for('user.index'))


# jwt
class UserLogoutAccess(Resource):
    @jwt_required()
    def post(self):
        jti = get_jwt()['jti']  # instead of get_raw_jwt
        try:
            revoked_token = RevokeTokenModel(jti=jti)
            revoked_token.add()
            return {'message': 'Accesss token has been revoked'}
        except:
            return {'message': 'Error occurred'}, 500


api.add_resource(UserLogoutAccess, '/logout/access')


class UserLogoutRefresh(Resource):
    @jwt_required(refresh=True)
    def post(self):
        jti = get_jwt()['jti']
        try:
            revoked_token = RevokeTokenModel(jti=jti)
            revoked_token.add()
            return {'message': 'Refresh token has been revoked'}
        except:
            return {'message': 'Error occurred'}, 500


api.add_resource(UserLogoutRefresh, '/logout/refresh')


# access-token刷新
class TokenRefresh(Resource):
    @jwt_required(refresh=True)  # @jwt_refresh_token_required -> @jwt_required(refresh=True)
    # We mean by this decorator that we can access this route using only a refresh token not an access token
    def post(self):
        # To extract identity from the refresh token and then use this identity to create an access token
        current_user = get_jwt_identity()
        access_token = create_access_token(identity=current_user)
        return {'access-token': access_token}


api.add_resource(TokenRefresh, '/token/refresh')


# jwt验证
class SecretResource(Resource):
    # @jwt_required()
    def get(self):
        # username = get_jwt_identity()
        # user = UserInfo.query.filter(UserInfo.username == username).first()
        # try:
            a=1/0
        # except Exception as e:
        #     user_bp1.logger.error(traceback.format_exc())

            return {
                'answer': '资源'
                # 'username': username,
                # 'phone': user.phone
            }

api.add_resource(SecretResource, '/secret')

ALLOWED_EXTENSIONS = ['jpg', 'png', 'gif', 'bmp']


# ------用户空间------
# 1. 决策中心
@user_bp1.route('/user/decision')
def user_decision():
    return render_template("decision.html")


# 2. 个人空间
@user_bp1.route('/user/space')
def user_space():
    return render_template("space.html")


# 3. 个人信息
@user_bp1.route('/user/info')
def user_info():
    return render_template("info.html")
